#include "transport/pps/pps.h"


/// String to identify log entries originating from this file.
static const std::string TAG("PPS");

/**
 * Create a LogEntry using this file's TAG and the specified event string.
 *
 * @param The event string for this @c LogEntry.
 */
// #define LE(event) logger::LogEntry(TAG, event)

static const unsigned int DATA_SIZE = 1024;

namespace motovis {
namespace transport {
namespace pps {

PPS::PPS(const std::string &channelName, const bool &model)
{
    m_channelName = channelName;
    if (model)
    {
        std::string open_str = m_channelName.append("wait?delta");
        printf(open_str.c_str());
        m_fd = open(open_str.c_str(), O_RDONLY);
    }
    else
    {
        m_fd = open(m_channelName.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
    }
    if (m_fd < 0) {
        printf("channel [%s] not found.\n", m_channelName.c_str());
        // MV_ERR(LE(__func__).d("A", model ? "subscribe" : "publish").d("couldn't open channel name", m_channelName));
    }

    m_receiveData.data = static_cast<void *>(new char[DATA_SIZE]());
    m_receiveData.dataSize = 0;
}

PPS::~PPS() 
{
    printf("[%s] pps destruct\n", m_channelName.c_str());
    delete [](char*)m_receiveData.data;
    m_thread->join();
}

bool PPS::publish(const void *data, const unsigned int dataLen)
{
    // MV_DEBUG(LE(__func__).d("Publish message", data).d("on channel name", m_channelName));
    printf("Publish data length: %d\n", dataLen);
    return ((write(m_fd, data, dataLen) == dataLen) ? true : false);
}

void PPS::subscribe(Callback &cb)
{
     m_thread = std::make_shared<std::thread>(std::bind(&PPS::exec, this, cb));
     printf("Subscribe channel name: %s\n", m_channelName.c_str());
     // MV_DEBUG(LE(__func__).d("Subscribe on channel name", m_channelName));
}


void PPS::exec(Callback &cb)
{
    printf("test 1\n");
    while (1)
    {
        m_receiveData.dataSize = read(m_fd, m_receiveData.data, DATA_SIZE);
        printf("test 2\n");
        if (m_receiveData.dataSize > 0)
        {
            printf("test 3\n");
            printf("Receive data size: %d\n", m_receiveData.dataSize);
            cb(&m_receiveData);
            printf("callback %s\n", m_channelName.c_str());
            // MV_DEBUG(LE(__func__).d("Callback is called on channel name", m_channelName));
        }
    }
}

//void PPS::exec(Callback &cb)
//{
//    int ret;
//    int timeout = 2000;
//    printf("test 1\n");
//
//    while (1)
//    {
//        struct pollfd readfds[1];
//        readfds[0].fd = m_fd;
//        readfds[0].events = POLLIN;
//        printf("test 2\n");
//        switch (ret = poll(readfds, 1, timeout))
//        {
//            case -1:
//                break;
//            case 0:
//                break;
//            default:
//                if (readfds[0].events & POLLRDNORM)
//                {
//                    m_receiveData.dataSize = read(m_fd, m_receiveData.data, DATA_SIZE);
//                    if (m_receiveData.dataSize > 0)
//                    {
//                        printf("test 3\n");
//                        printf("Receive data size: %d\n", m_receiveData.dataSize);
//                        cb(&m_receiveData);
//                        printf("callback %s\n", m_channelName.c_str());
//                        // MV_DEBUG(LE(__func__).d("Callback is called on channel name", m_channelName));
//                    }
//                }
//                break;
//        }
//    }
//}

//void PPS::exec(Callback &cb)
//{
//    fd_set readfds;
//    while (1)
//    {
//        printf("test 0\n");
//        FD_ZERO(&readfds);
//        FD_SET(m_fd, &readfds);
//        if (select(m_fd + 1, &readfds, nullptr, nullptr, nullptr) > 0)
//        {
//            printf("test 1\n");
//            if(FD_ISSET(m_fd, &readfds))
//            {
//                printf("test 2\n");
//                m_receiveData.dataSize = read(m_fd, m_receiveData.data, DATA_SIZE);
//                if (m_receiveData.dataSize > 0)
//                {
//                    printf("test 3\n");
//                    printf("Receive data size: %d\n", m_receiveData.dataSize);
//                    cb(&m_receiveData);
//                    printf("callback %s\n", m_channelName.c_str());
//                    // MV_DEBUG(LE(__func__).d("Callback is called on channel name", m_channelName));
//                }
//                memset(m_receiveData.data, 0, DATA_SIZE);
//                m_receiveData.dataSize = 0;
//            }
//        }
//    }
//}

} // namespace pps
} // namespace transport
} // namespace motovis

